<template>
  <el-dialog
    v-model="visible"
    :title="file?.title || '编辑文件'"
    width="80%"
    :close-on-click-modal="false"
    @close="handleClose"
    class="knowledge-editor-dialog"
  >
    <div v-loading="loading" class="editor-container">
      <div class="editor-header">
        <el-tag v-if="file?.format === 'md'" type="info">Markdown</el-tag>
        <el-tag v-else-if="file?.format === 'html'" type="warning">HTML</el-tag>
        <el-tag v-else type="success">文本</el-tag>
        <div class="editor-actions">
          <el-button size="small" @click="handlePreview" v-if="file?.format === 'md'">
            <el-icon><View /></el-icon>
            预览
          </el-button>
        </div>
      </div>

      <div class="editor-content" v-if="!loading">
        <!-- Markdown编辑器（分屏模式） -->
        <div v-if="file?.format === 'md' && showPreview" class="markdown-editor-split">
          <div class="editor-pane">
            <div class="pane-header">编辑</div>
            <textarea
              ref="editorRef"
              v-model="content"
              class="markdown-editor"
              placeholder="输入Markdown内容..."
              @input="handleContentChange"
            ></textarea>
          </div>
          <div class="preview-pane">
            <div class="pane-header">预览</div>
            <div class="markdown-preview" v-html="renderedMarkdown"></div>
          </div>
        </div>

        <!-- 单编辑器模式 -->
        <div v-else class="single-editor">
          <textarea
            ref="editorRef"
            v-model="content"
            :class="['text-editor', { 'markdown-editor': file?.format === 'md' }]"
            :placeholder="`输入${file?.format === 'md' ? 'Markdown' : file?.format === 'html' ? 'HTML' : '文本'}内容...`"
            @input="handleContentChange"
          ></textarea>
        </div>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleSave" :loading="saving">
          <el-icon><Check /></el-icon>
          保存
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { View, Check } from '@element-plus/icons-vue'
import { getKnowledgeFileContent, saveKnowledgeFileContent } from '@/api/knowledge'
import type { KnowledgeFile } from '@/api/knowledge'
import { marked } from 'marked'

interface Props {
  modelValue: boolean
  file: KnowledgeFile | null
}

interface Emits {
  (e: 'update:modelValue', value: boolean): void
  (e: 'saved', file: KnowledgeFile): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const visible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

const loading = ref(false)
const saving = ref(false)
const content = ref('')
const file = ref<KnowledgeFile | null>(null)
const editorRef = ref<HTMLTextAreaElement | null>(null)
const showPreview = ref(true)
const hasChanges = ref(false)

// 渲染Markdown
const renderedMarkdown = computed(() => {
  if (content.value && file.value?.format === 'md') {
    try {
      return marked(content.value)
    } catch (e) {
      return content.value
    }
  }
  return ''
})

// 加载文件内容
const loadContent = async () => {
  if (!props.file) return

  loading.value = true
  try {
    file.value = props.file
    const response = await getKnowledgeFileContent(props.file.id)
    content.value = response.data.data.content
    hasChanges.value = false

    // 聚焦编辑器
    await nextTick()
    if (editorRef.value) {
      editorRef.value.focus()
    }
  } catch (error: any) {
    console.error('加载文件内容失败:', error)
    ElMessage.error('加载文件内容失败: ' + (error?.message || '未知错误'))
  } finally {
    loading.value = false
  }
}

// 内容变化
const handleContentChange = () => {
  hasChanges.value = true
}

// 切换预览
const handlePreview = () => {
  showPreview.value = !showPreview.value
}

// 保存文件
const handleSave = async () => {
  if (!file.value) return

  saving.value = true
  try {
    const response = await saveKnowledgeFileContent(file.value.id, content.value)
    ElMessage.success('保存成功')
    hasChanges.value = false
    emit('saved', response.data.data)
    handleClose()
  } catch (error: any) {
    console.error('保存失败:', error)
    ElMessage.error('保存失败: ' + (error?.message || '未知错误'))
  } finally {
    saving.value = false
  }
}

// 关闭对话框
const handleClose = () => {
  if (hasChanges.value) {
    // 可以添加确认对话框
    // 这里直接关闭
  }
  visible.value = false
  content.value = ''
  file.value = null
  hasChanges.value = false
}

// 监听对话框打开
watch(visible, (val) => {
  if (val) {
    loadContent()
  }
})

// 监听文件变化
watch(() => props.file, () => {
  if (visible.value && props.file) {
    loadContent()
  }
})
</script>

<style scoped lang="scss">
.knowledge-editor-dialog {
  .editor-container {
    min-height: 500px;
    display: flex;
    flex-direction: column;
  }

  .editor-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 0;
    border-bottom: 1px solid var(--el-border-color);
    margin-bottom: 16px;

    .editor-actions {
      display: flex;
      gap: 8px;
    }
  }

  .editor-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 500px;
  }

  .markdown-editor-split {
    display: flex;
    gap: 16px;
    height: 70vh;

    .editor-pane,
    .preview-pane {
      flex: 1;
      display: flex;
      flex-direction: column;
      border: 1px solid var(--el-border-color);
      border-radius: 4px;
      overflow: hidden;

      .pane-header {
        padding: 8px 12px;
        background: var(--el-fill-color-light);
        border-bottom: 1px solid var(--el-border-color);
        font-size: 14px;
        font-weight: 500;
      }
    }

    .editor-pane {
      .markdown-editor {
        flex: 1;
        width: 100%;
        padding: 16px;
        border: none;
        outline: none;
        resize: none;
        font-family: 'Courier New', monospace;
        font-size: 14px;
        line-height: 1.6;
      }
    }

    .preview-pane {
      overflow: auto;
      background: #fff;

      .markdown-preview {
        flex: 1;
        padding: 20px;
        line-height: 1.6;

        :deep(h1),
        :deep(h2),
        :deep(h3) {
          margin-top: 24px;
          margin-bottom: 16px;
          font-weight: 600;
        }

        :deep(p) {
          margin-bottom: 16px;
        }

        :deep(code) {
          background: #f5f5f5;
          padding: 2px 6px;
          border-radius: 3px;
          font-family: 'Courier New', monospace;
        }

        :deep(pre) {
          background: #f5f5f5;
          padding: 16px;
          border-radius: 4px;
          overflow-x: auto;
        }

        :deep(blockquote) {
          border-left: 4px solid #ddd;
          padding-left: 16px;
          margin: 16px 0;
          color: #666;
        }
      }
    }
  }

  .single-editor {
    flex: 1;
    display: flex;
    flex-direction: column;

    .text-editor {
      flex: 1;
      width: 100%;
      padding: 16px;
      border: 1px solid var(--el-border-color);
      border-radius: 4px;
      outline: none;
      resize: none;
      font-family: 'Courier New', monospace;
      font-size: 14px;
      line-height: 1.6;
      min-height: 70vh;

      &:focus {
        border-color: var(--el-color-primary);
      }
    }

    .markdown-editor {
      font-family: 'Courier New', monospace;
    }
  }

  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
  }
}
</style>

